package com.bgds.sys.api.project.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bgds.sys.api.project.constant.TypeEunum;
import com.bgds.sys.api.project.request.ProjectRequest;
import com.bgds.sys.api.project.response.ProjectExcel;
import com.bgds.sys.api.project.service.ProjectService;
import com.bgds.sys.module.entity.project.Project;
import com.bgds.sys.module.entity.project.ProjectItem;
import com.bgds.sys.module.mapper.ProjectItemMapper;
import com.bgds.sys.module.mapper.ProjectMapper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author chenchao
 * @date 2021/9/14
 */
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements ProjectService {

    @Resource
    private ProjectItemMapper projectItemMapper;

    @Override
    public IPage<Project> pageList(ProjectRequest request) {
        return this.page(new Page(request.getPageNum(), request.getPageSize())
                , new QueryWrapper<Project>().lambda()
                        .like(StrUtil.isNotBlank(request.getArea()), Project::getArea, request.getArea())
                        .like(StrUtil.isNotBlank(request.getDeviceName()), Project::getDeviceName, request.getDeviceName())
                        .like(StrUtil.isNotBlank(request.getManageProject()), Project::getManageProject, request.getManageProject())
                        .like(StrUtil.isNotBlank(request.getDrawingSize()), Project::getDrawingSize, request.getDrawingSize())
                        .like(StrUtil.isNotBlank(request.getManageNorm()), Project::getManageNorm, request.getManageNorm())
                        .like(StrUtil.isNotBlank(request.getAccountabilityUnit()), Project::getAccountabilityUnit, request.getAccountabilityUnit())
                        .like(StrUtil.isNotBlank(request.getSubmissionUnit()), Project::getSubmissionUnit, request.getSubmissionUnit())
                        .like(StrUtil.isNotBlank(request.getControlRank()), Project::getControlRank, request.getControlRank())
                        .like(StrUtil.isNotBlank(request.getMeasuringMethod()), Project::getMeasuringMethod, request.getMeasuringMethod())
                        .like(StrUtil.isNotBlank(request.getMeasuringAsk()), Project::getMeasuringAsk, request.getMeasuringAsk())
                        .orderByAsc(Project::getSequence)
        );
    }

    @Override
    public void deleteProject(Long id) {
        projectItemMapper.delete(new QueryWrapper<ProjectItem>().lambda().eq(ProjectItem::getProjectId, id));
        baseMapper.deleteById(id);
    }

    @Override
    public Project getProject(Long id) {
        return baseMapper.selectOne(new QueryWrapper<Project>().lambda().eq(Project::getId, id));
    }

    @Override
    public void addProject(Project project) {
        String code = null;
        Integer suffix = baseMapper.calculateTheAccumulatedValue() != null ? baseMapper.calculateTheAccumulatedValue() : TypeEunum.FUNCTION.getSuffix();
        if (TypeEunum.FUNCTION.getMessage().equals(project.getType())) {
            //功能
            code = TypeEunum.FUNCTION.getPrefix()
                    + DateUtil.format(new Date(), TypeEunum.FUNCTION.getTime()
                    + suffix);
        }
        if (TypeEunum.PRECISION.getMessage().equals(project.getType())) {
            //精度
            code += TypeEunum.PRECISION.getPrefix()
                    + DateUtil.format(new Date(), TypeEunum.PRECISION.getTime()
                    + suffix);
        }

        if (StrUtil.isNotBlank(code)) {
            project.setCode(code);
        } else {
            throw new RuntimeException("类型必须是功能或者精度!");
        }

        baseMapper.insert(project);
    }

    @Override
    public void saveProject(Project project) {
        baseMapper.updateById(project);
    }

    @Override
    public void export(HttpServletResponse response, String ids) {
        List<Project> projects;
        if (StrUtil.isNotBlank(ids)) {
            projects = baseMapper.selectList(new QueryWrapper<Project>().lambda().in(Project::getId, ids.split(StrUtil.COMMA)));
        } else {
            projects = baseMapper.selectList(null);
        }
        if (projects.isEmpty()) {
            return;
        }
        List<ProjectExcel> data = projects.stream().map(project -> Convert.convert(ProjectExcel.class, project)).collect(Collectors.toList());
        // 通过工具类创建writer，默认创建xls格式
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //自定义标题别名
        writer.addHeaderAlias("code", "编码");
        writer.addHeaderAlias("type", "类型");
        writer.addHeaderAlias("sequence", "序号");
        writer.addHeaderAlias("area", "区域");
        writer.addHeaderAlias("deviceName", "设备名称");
        writer.addHeaderAlias("manageProject", "管理项目");
        writer.addHeaderAlias("manageNorm", "管理标准");
        writer.addHeaderAlias("accountabilityUnit", "责任单位");
        writer.addHeaderAlias("submissionUnit", "结果提报单位");
        writer.addHeaderAlias("controlRank", "管控级别");
        writer.addHeaderAlias("measuringMethod", "检测方法");
        writer.addHeaderAlias("period", "评价周期");
        writer.addHeaderAlias("measuringAsk", "测量要求");
        writer.addHeaderAlias("createUser", "编制人");
        writer.addHeaderAlias("createTime", "编制时间");

        // 设置行宽
        writer.setColumnWidth(1, 40);
        writer.setColumnWidth(2, 40);
        writer.setColumnWidth(3, 40);
        writer.setColumnWidth(4, 40);
        writer.setColumnWidth(5, 40);
        writer.setColumnWidth(6, 40);
        writer.setColumnWidth(7, 40);
        writer.setColumnWidth(8, 40);
        writer.setColumnWidth(9, 40);
        writer.setColumnWidth(10, 40);
        writer.setColumnWidth(11, 40);
        writer.setColumnWidth(12, 40);
        writer.setColumnWidth(13, 40);
        writer.setColumnWidth(14, 40);
        writer.setColumnWidth(15, 40);
        // 设置行高
        writer.setDefaultRowHeight(30);
        // 写出内容
        writer.write(data, true);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + DateUtil.now() + ".xlsx");

        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            writer.flush(out, true);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭writer，释放内存
            writer.close();
        }
        // 关闭输出Servlet流
        IoUtil.close(out);
    }

    @Override
    public void Import(MultipartFile file) {
        ExcelReader reader = null;
        try {
            reader = ExcelUtil.getReader(file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        reader.read(1).forEach(item -> {
            Project project = new Project();
            project.setType((String) item.get(0));
            project.setSequence(((Long) item.get(1)).intValue());
            project.setArea((String) item.get(2));
            project.setDeviceName((String) item.get(3));
            project.setManageProject((String) item.get(4));
            project.setManageNorm((String) item.get(5));
            project.setAccountabilityUnit((String) item.get(6));
            project.setSubmissionUnit((String) item.get(7));
            project.setControlRank((String) item.get(8));
            project.setMeasuringMethod((String) item.get(9));
            project.setPeriod((String) item.get(10));
            project.setMeasuringAsk((String) item.get(11));
            addProject(project);
        });


    }


}
